package com.xixilala.myapplication

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Environment
import android.util.Log
import android.util.Size
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import java.io.File
import java.util.concurrent.Executor

/**
 * Created by hc on 2021.2.14.
 */
class CameraFragment : BaseFragment() {
    private val TAG = "HHHH_camera"
    private val BLOCK_SIZE = 3

    private val TIME_DELAY:Long = 3 * 1000

    private var step = 0
    private lateinit var camera: Camera
    private lateinit var cameraExecutor: Executor
    private lateinit var imageCapture: ImageCapture
    private lateinit var preview: Preview
    private var parentWidth  = 0
    private var parentHeight = 0
    private var childHeight  = 0

    private lateinit var flParent:FrameLayout
    private lateinit var pvCamera: PreviewView
    private lateinit var btnStart: Button
    private lateinit var tvTime0:TextView
    private lateinit var tvTime1:TextView
    private lateinit var tvTime2:TextView

    private lateinit var ivPreviewResult0:ImageView
    private lateinit var ivPreviewResult1:ImageView
    private lateinit var ivPreviewResult2:ImageView

    private val ivList = ArrayList<ImageView>(BLOCK_SIZE)
    private val tvList = ArrayList<TextView>(BLOCK_SIZE)

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_camera, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        flParent = view.findViewById(R.id.flParent)
        pvCamera = view.findViewById(R.id.pvCamera)
        btnStart = view.findViewById(R.id.btnStart)

        tvTime0 = view.findViewById(R.id.tvTime0)
        tvTime1 = view.findViewById(R.id.tvTime1)
        tvTime2 = view.findViewById(R.id.tvTime2)

        ivPreviewResult0 = view.findViewById(R.id.ivPreviewResult0)
        ivPreviewResult1 = view.findViewById(R.id.ivPreviewResult1)
        ivPreviewResult2 = view.findViewById(R.id.ivPreviewResult2)

        fun initView() {
            btnStart.setOnClickListener{
                ivList.forEach {iv-> iv.setImageBitmap(null) }
                it.visibility = View.GONE
                takePic()
            }
            flParent.post {
                parentWidth = flParent.measuredWidth
                parentHeight = flParent.measuredHeight
                childHeight = parentHeight/BLOCK_SIZE

                initCamera()
            }
        }

        initView()

        ivList.apply {
            add(ivPreviewResult0)
            add(ivPreviewResult1)
            add(ivPreviewResult2)
        }
        tvList.apply {
            add(tvTime0)
            add(tvTime1)
            add(tvTime2)
        }
    }

    private fun initCamera() {
        val processCameraProvider = ProcessCameraProvider.getInstance(_activity)
        cameraExecutor = ContextCompat.getMainExecutor(_activity)

        processCameraProvider.addListener(Runnable {
            val cameraProvider = processCameraProvider.get()

            preview = Preview.Builder()
                    .build()

            imageCapture = ImageCapture.Builder()
                    .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
//                    .setTargetResolution(Size(parentWidth, childHeight*(which+1)))

                    .build()

            val cameraSelector = CameraSelector.Builder()
                    .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                    .build()

            val imageAnalysis = ImageAnalysis.Builder()
                    .setTargetResolution(Size(1280, 720))
                    .build()

            camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture,imageAnalysis)

            preview.setSurfaceProvider(pvCamera.surfaceProvider)
        }, cameraExecutor)
    }

    private fun takePic() {
        if (step >= BLOCK_SIZE) {
            step = 0

            return
        }
        val tempStep = step
        tvList[tempStep].text = "${TIME_DELAY/1000}s"
        val cdt = object  : CountDownTimer(TIME_DELAY, 1000) {
            override fun onFinish() {
                takePicInner(tempStep)
                tvList[tempStep].visibility = View.INVISIBLE
            }

            override fun onTick(p0: Long) {
                //TODO 大变小文字动画
                tvList[tempStep].text = "${p0/1000}s"
                tvList[tempStep].visibility = View.VISIBLE
            }
        }
        cdt.start()
    }

    private fun takePicInner(which: Int = step) {
        val file = File(Environment.getExternalStorageDirectory().absolutePath + File.separator + Environment.DIRECTORY_PICTURES, "${which}.png")
        if (file.exists()) {
            file.delete()
            file.createNewFile()
        }
        val outputFileOptions = ImageCapture.OutputFileOptions.Builder(file).build()
        imageCapture.takePicture(outputFileOptions, cameraExecutor, object : ImageCapture.OnImageSavedCallback {
            override fun onError(error: ImageCaptureException) {
                Log.e(TAG, "error ${error.localizedMessage}")
            }

            override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {

                val bm = BitmapFactory.decodeFile(file.absolutePath)
                val pw = bm.width
                val ph = bm.height
                val ch = ph / BLOCK_SIZE
                val resBm = Bitmap.createBitmap(bm, 0, ch * which, pw, ch)
                ivList[which].setImageBitmap(resBm)


                if (BLOCK_SIZE-1 == which) {
                    btnStart.visibility = View.VISIBLE
                }
                step ++

                takePic()
            }
        })
    }
}


